import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(primarySwatch: Colors.blue),
      home: const GestureDemoHome(),
    );
  }
}

class GestureDemoHome extends StatefulWidget {
  const GestureDemoHome({super.key});

  @override
  State<GestureDemoHome> createState() => _GestureDemoHomeState();
}

class _GestureDemoHomeState extends State<GestureDemoHome> {
  int _currentIndex = 0;
  
  // 定义不同手势页面
  final List<Widget> _pages = [
    const TapGestureDemo(),
    const DragGestureDemo(),
    const ScaleGestureDemo(),
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Flutter手势演示')),
      body: _pages[_currentIndex],
      bottomNavigationBar: BottomNavigationBar(
        currentIndex: _currentIndex,
        onTap: (index) => setState(() => _currentIndex = index),
        items: const [
          BottomNavigationBarItem(icon: Icon(Icons.touch_app), label: '点击/长按'),
          BottomNavigationBarItem(icon: Icon(Icons.drag_handle), label: '拖动/滑动'),
          BottomNavigationBarItem(icon: Icon(Icons.zoom_in), label: '缩放'),
        ],
      ),
    );
  }
}

// 1. 点击、双击、长按手势
class TapGestureDemo extends StatefulWidget {
  const TapGestureDemo({super.key});

  @override
  State<TapGestureDemo> createState() => _TapGestureDemoState();
}

class _TapGestureDemoState extends State<TapGestureDemo> {
  String _lastGesture = '等待手势...';
  Color _color = Colors.blue;
  double _opacity = 1.0;

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(16.0),
      child: Card(
        elevation: 4,
        child: Padding(
          padding: const EdgeInsets.all(16.0),
          child: Column(
            children: [
              const Text(
                '基本手势操作',
                style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
              ),
              const SizedBox(height: 20),
              GestureDetector(
                onTap: () => setState(() {
                  _lastGesture = '点击';
                  _color = Colors.blue;
                  _opacity = 1.0;
                }),
                onDoubleTap: () => setState(() {
                  _lastGesture = '双击';
                  _color = Colors.green;
                  _opacity = 1.0;
                }),
                onLongPress: () => setState(() {
                  _lastGesture = '长按';
                  _color = Colors.red;
                  _opacity = 0.7;
                }),
                onTapDown: (_) => setState(() => _opacity = 0.5),
                onTapUp: (_) => setState(() => _opacity = 1.0),
                onTapCancel: () => setState(() => _opacity = 1.0),
                child: AnimatedContainer(
                  duration: const Duration(milliseconds: 300),
                  width: 200,
                  height: 200,
                  color: _color.withOpacity(_opacity),
                  alignment: Alignment.center,
                  child: const Text(
                    '点击我',
                    style: TextStyle(color: Colors.white, fontSize: 20),
                  ),
                ),
              ),
              const SizedBox(height: 20),
              Text('最后操作: $_lastGesture', style: const TextStyle(fontSize: 16)),
            ],
          ),
        ),
      ),
    );
  }
}

// 2. 拖动和滑动手势
class DragGestureDemo extends StatefulWidget {
  const DragGestureDemo({super.key});

  @override
  State<DragGestureDemo> createState() => _DragGestureDemoState();
}

class _DragGestureDemoState extends State<DragGestureDemo> {
  // 任意方向拖动
  double _xPosition = 0;
  double _yPosition = 0;
  
  // 垂直滑动
  double _verticalPosition = 100;
  
  // 水平滑动
  double _horizontalPosition = 100;
  
  // 记录最后操作
  String _lastOperation = '等待操作...';

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(16.0),
      child: ListView(
        children: [
          Card(
            elevation: 4,
            child: Padding(
              padding: const EdgeInsets.all(16.0),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  const Text(
                    '任意方向拖动',
                    style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
                  ),
                  const SizedBox(height: 10),
                  const Text(
                    '长按并拖动下方圆形',
                    style: TextStyle(color: Colors.grey),
                  ),
                  const SizedBox(height: 20),
                  SizedBox(
                    height: 200,
                    child: Stack(
                      children: [
                        Positioned(
                          left: _xPosition,
                          top: _yPosition,
                          child: GestureDetector(
                            onPanStart: (details) {
                              setState(() => _lastOperation = '开始拖动');
                            },
                            onPanUpdate: (details) {
                              setState(() {
                                _xPosition += details.delta.dx;
                                _yPosition += details.delta.dy;
                                _lastOperation = '拖动中 (${_xPosition.toStringAsFixed(1)}, ${_yPosition.toStringAsFixed(1)})';
                              });
                            },
                            onPanEnd: (details) {
                              final velocity = details.velocity.pixelsPerSecond;
                              setState(() => _lastOperation = '拖动结束\n速度: ${velocity.distance.toStringAsFixed(1)} px/s');
                            },
                            child: Container(
                              width: 50,
                              height: 50,
                              decoration: const BoxDecoration(
                                shape: BoxShape.circle,
                                color: Colors.blue,
                              ),
                              child: const Center(child: Text('A', style: TextStyle(color: Colors.white))),
                            ),
                          ),
                        ),
                      ],
                    ),
                  ),
                  const SizedBox(height: 10),
                  Text(_lastOperation, style: const TextStyle(fontSize: 14)),
                ],
              ),
            ),
          ),
          
          const SizedBox(height: 20),
          
          Card(
            elevation: 4,
            child: Padding(
              padding: const EdgeInsets.all(16.0),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  const Text(
                    '垂直滑动',
                    style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
                  ),
                  const SizedBox(height: 10),
                  const Text(
                    '只能上下滑动，左右方向无效',
                    style: TextStyle(color: Colors.grey),
                  ),
                  const SizedBox(height: 20),
                  SizedBox(
                    height: 200,
                    child: Stack(
                      children: [
                        Positioned(
                          left: 50,
                          top: _verticalPosition,
                          child: GestureDetector(
                            onVerticalDragUpdate: (details) {
                              setState(() {
                                _verticalPosition += details.delta.dy;
                                // 限制边界
                                _verticalPosition = _verticalPosition.clamp(0.0, 150.0);
                              });
                            },
                            child: Container(
                              width: 50,
                              height: 50,
                              decoration: const BoxDecoration(
                                shape: BoxShape.circle,
                                color: Colors.green,
                              ),
                              child: const Center(child: Text('↑↓', style: TextStyle(color: Colors.white))),
                            ),
                          ),
                        ),
                      ],
                    ),
                  ),
                ],
              ),
            ),
          ),
          
          const SizedBox(height: 20),
          
          Card(
            elevation: 4,
            child: Padding(
              padding: const EdgeInsets.all(16.0),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  const Text(
                    '水平滑动',
                    style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
                  ),
                  const SizedBox(height: 10),
                  const Text(
                    '只能左右滑动，上下方向无效',
                    style: TextStyle(color: Colors.grey),
                  ),
                  const SizedBox(height: 20),
                  SizedBox(
                    height: 100,
                    child: Stack(
                      children: [
                        Positioned(
                          left: _horizontalPosition,
                          top: 25,
                          child: GestureDetector(
                            onHorizontalDragUpdate: (details) {
                              setState(() {
                                _horizontalPosition += details.delta.dx;
                                // 限制边界
                                _horizontalPosition = _horizontalPosition.clamp(0.0, 250.0);
                              });
                            },
                            child: Container(
                              width: 50,
                              height: 50,
                              decoration: const BoxDecoration(
                                shape: BoxShape.circle,
                                color: Colors.orange,
                              ),
                              child: const Center(child: Text('←→', style: TextStyle(color: Colors.white))),
                            ),
                          ),
                        ),
                      ],
                    ),
                  ),
                ],
              ),
            ),
          ),
        ],
      ),
    );
  }
}

// 3. 缩放手势
class ScaleGestureDemo extends StatefulWidget {
  const ScaleGestureDemo({super.key});

  @override
  State<ScaleGestureDemo> createState() => _ScaleGestureDemoState();
}

class _ScaleGestureDemoState extends State<ScaleGestureDemo> {
  double _scale = 1.0;
  double _previousScale = 1.0;
  String _lastScale = '初始大小';
  
  // 示例图片URL（使用Flutter官方图片）
  final String _imageUrl = 'https://picsum.photos/id/237/600/400';

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(16.0),
      child: Card(
        elevation: 4,
        child: Padding(
          padding: const EdgeInsets.all(16.0),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              const Text(
                '图片缩放',
                style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
              ),
              const SizedBox(height: 10),
              const Text(
                '使用双指张开/收缩进行缩放',
                style: TextStyle(color: Colors.grey),
              ),
              const SizedBox(height: 20),
              Center(
                child: GestureDetector(
                  onScaleStart: (details) {
                    _previousScale = _scale;
                    setState(() => _lastScale = '开始缩放');
                  },
                  onScaleUpdate: (details) {
                    setState(() {
                      _scale = _previousScale * details.scale;
                      // 限制缩放范围
                      _scale = _scale.clamp(0.5, 3.0);
                      _lastScale = '缩放比例: ${_scale.toStringAsFixed(2)}x';
                    });
                  },
                  onScaleEnd: (details) {
                    _previousScale = 1.0;
                    setState(() => _lastScale = '缩放结束: ${_scale.toStringAsFixed(2)}x');
                  },
                  child: AnimatedScale(
                    scale: _scale,
                    duration: const Duration(milliseconds: 100),
                    child: Container(
                      width: 200,
                      height: 150,
                      decoration: BoxDecoration(
                        borderRadius: BorderRadius.circular(8),
                        boxShadow: [
                          BoxShadow(
                            color: Colors.black.withOpacity(0.2),
                            blurRadius: 8,
                            offset: const Offset(0, 4),
                          ),
                        ],
                      ),
                      child: ClipRRect(
                        borderRadius: BorderRadius.circular(8),
                        child: Image.network(
                          _imageUrl,
                          fit: BoxFit.cover,
                          errorBuilder: (context, error, stackTrace) {
                            return Container(
                              color: Colors.grey[300],
                              child: const Center(
                                child: Icon(Icons.error, color: Colors.red),
                              ),
                            );
                          },
                        ),
                      ),
                    ),
                  ),
                ),
              ),
              const SizedBox(height: 20),
              Center(child: Text(_lastScale, style: const TextStyle(fontSize: 16))),
            ],
          ),
        ),
      ),
    );
  }
}
